# -*- coding: utf-8 -*-
import uuid

from sqlalchemy import or_, func

from db.session import with_session
from db.models.files import DualControlFile
from utils.file_utils import to_rel_path


""" =========================== DualControlFile ================================ """
# 查找 所有双控文件
@with_session
def db_get_dc_files(session, *, name_like: str = None, offset: int = 0, limit: int = 50):
    query = session.query(DualControlFile).filter(DualControlFile.is_delete.is_(False))
    if name_like:
        query = query.filter(DualControlFile.name.ilike(f"%{name_like}%"))
    total = query.count()
    items = query.order_by(DualControlFile.create_time.desc()).offset(offset).limit(limit).all()
    return items, total


# 根据用户组ID列表获取双控文件
@with_session
def db_get_dc_files_by_user_groups(session, user_group_ids, *, name_like: str = None, offset: int = 0, limit: int = 50):
    """根据用户组ID列表获取双控文件"""
    if not user_group_ids:
        return [], 0
    
    # 查询文件：要么group_ids为空（所有用户可访问），要么包含用户的组ID
    # 由于ARRAY类型存储为JSON，需要使用JSON函数进行查询
    query = session.query(DualControlFile) \
        .filter(DualControlFile.is_delete.is_(False)) \
        .filter(
            or_(
                DualControlFile.group_ids == [],  # 空数组表示所有用户可访问
                func.json_contains(DualControlFile.group_ids, str(user_group_ids))  # 与用户组ID有交集
            )
        )
    if name_like:
        query = query.filter(DualControlFile.name.ilike(f"%{name_like}%"))
    total = query.count()
    items = query.order_by(DualControlFile.create_time.desc()).offset(offset).limit(limit).all()
    return items, total


# 查找 根据文件id查找
@with_session
def db_get_dc_file_by_id(session, file_id: uuid.UUID):
    return session.query(DualControlFile).filter(DualControlFile.id == file_id, DualControlFile.is_delete.is_(False)).first()


# 查找 根据文件名称查找
@with_session
def db_get_dc_file_by_name(session, file_hash_name):
    return session.query(DualControlFile) \
        .filter(DualControlFile.hash_name == file_hash_name, DualControlFile.is_delete.is_(False)) \
        .first()


# 按原始文件名模糊查询，逻辑未删除
@with_session
def db_get_dc_files_by_origin_name(session, name_like: str):
    """按原始文件名模糊查询，逻辑未删除"""
    if not name_like:
        return session.query(DualControlFile).filter(DualControlFile.is_delete.is_(False)).all()
    return session.query(DualControlFile) \
        .filter(DualControlFile.is_delete.is_(False)) \
        .filter(DualControlFile.name.ilike(f"%{name_like}%")) \
        .all()


# 添加双控文件
@with_session
def db_add_dc_file(session, user_id: int, hash_name: str, file_name: str, location: str, file_type: str, size: float, group_ids: list[int] = None):
    f = session.query(DualControlFile).filter(DualControlFile.hash_name == hash_name).first()
    if f:
        f.is_delete = False
        f.created_by = user_id
        f.name = file_name
        f.hash_name = hash_name
        f.location = to_rel_path(location)
        f.file_type = file_type
        f.file_size = size
        if group_ids is not None:
            f.group_ids = group_ids
        session.commit()
        return f, True
    new_file = DualControlFile(
        created_by=user_id,
        name=file_name,
        hash_name=hash_name,
        location=to_rel_path(location),
        file_type=file_type,
        file_size=size,
        group_ids=group_ids or []
    )
    session.add(new_file)
    session.commit()
    return new_file, False


# 更新双控文件删除状态
@with_session
def db_update_dc_file_delete_state(session, file_id: uuid.UUID, delete: bool):
    file = session.query(DualControlFile).get(file_id)
    if not file:
        return None
    file.is_delete = delete
    session.commit()
    return True


# 更新双控文件信息（文件名或用户组）
@with_session
def db_update_dc_file_info(session, file_id: uuid.UUID, name: str = None, group_ids: list[int] = None):
    """更新双控文件信息（文件名或用户组）"""
    file = session.query(DualControlFile).get(file_id)
    if not file:
        return None
    if name is not None:
        file.name = name
    if group_ids is not None:
        file.group_ids = group_ids
    session.commit()
    return file
